﻿/*
函数说明：用于构造树。
*/  

function buildTree(
    panelDivObj,    //Container div object for panel, e.g. var panelDivObj = document.getElementById("panel1");
    treeDivObj,     //Container div object for tree,  e.g. var treeDivObj = document.getElementById("treeDiv1");
    className,      //The class name of aspx.cs,      e.g. var className = MetaDataEdit;
    param,          //The parameter for callback function LoadDatas
    confrimButtonText,
    cancelButtonText,
    width,          //The width of panel, default is 25em
    //when listObj is not null, returnCodeObj and returnNameObj are null
    returnCodeObj,  //The object for return value after node clicked, e.g. var returnCodeObj = document.getElementById("<%= codeHiddenTextBox.ClientID %>");
    returnNameObj,  //The object for return text after node clicked,  e.g. var returnNameObj = document.getElementById("<%= nameTextBox.ClientID %>");
    listObj,        //The ListBox object,          e.g. var listObj = document.getElementById("<%= tempListBox.ClientID %>");
    //when isDialog is true, isfixedcenter must be true, targetObjId must be null
    isDialog,       //True for showing dialog with title bar, default is true
    isfixedcenter,  //True for showing dialog on the center of the page, default is true
    targetObjId,    //The ID of target object,     e.g. var targetObj = "add_range";
    isExpandWhenClick,         //True for expand but reutrn value when click un-leaf node
        //when isNotCheck is true, isNotOnlyLeafCheck and isNotWhenCheckOnlyReturnLeaf are usefully
    isNotCheck,        //True for building checkbox tree. default is true
    isNotOnlyLeafCheck,//True for only show checkbox on leaf node, default is true
    isNotWhenCheckOnlyReturnLeaf, //True for only return leaf nodes values. default is true
    //
    splitChar,      //The seprator of returned values, default is ","
    isNotReturnMetaData          //True for return node.data.MetaData, false for return node.data.label, default is true
    ) {

    //Validate parameters begin
    if (panelDivObj == null) {
        alert("panelDivObj can not be null.");
        return;
    } else if (treeDivObj == null) {
        alert("treeDivObj can not be null.");
        return;
    } else if (className == null) {
        alert("className can not be null.");
        return;
    } else if (listObj == null && (returnCodeObj == null || returnNameObj == null)
           || (listObj != null && (returnCodeObj != null || returnNameObj != null))
           ) {
        alert("listObj and returnCodeObj can not be null either.");
        return;
    } else if (targetObjId != null && isfixedcenter) {
        alert("When targetObjId is not null, isfixedcenter should be false.");
        return;
    }
    //Validate parameters end

    YAHOO.namespace("example.container");
    YAHOO.example.container.dialog1 = null;
    
    var oResults;
    var tree;
    var dialog;
    var checkedNodesList;
    var fixedcenter;
    
    //Init default parameters
    if (param == null) param = "";
    if (width == null) width = "25em";
    if (isDialog == null) isDialog = true;
    if (fixedcenter == null) fixedcenter = true;
    if (isExpandWhenClick == null) isExpandWhenClick = true;  
    if (isNotCheck == null) isNotCheck = true;
    if (isNotOnlyLeafCheck == null) isNotOnlyLeafCheck = true;
    if (isNotWhenCheckOnlyReturnLeaf == null) isNotWhenCheckOnlyReturnLeaf = true; //default is return all nodes' value
    if (splitChar == null) splitChar = ","; //default is ,
    if (isNotReturnMetaData == null) isNotReturnMetaData = true;
    
    if (isDialog) dialog = YAHOO.example.container.dialog1;

    //Handle for tree with checkbox begin
    var handleSubmit = function() {
    
        checkedNodesList = getCheckedNodes(tree.getRoot().children);
        
        var codes = "";  //for return code values e.g. id1,id2,id3
        var values = ""; //for return labels      e.g. string1,string2,string3
        for (var i = 0; i < checkedNodesList.length; i++) {
            //do when not isNotWhenCheckOnlyReturnLeaf or is leaf and isNotWhenCheckOnlyReturnLeaf
            if (isNotWhenCheckOnlyReturnLeaf || !isNotWhenCheckOnlyReturnLeaf && checkedNodesList[i].children.length == 0) {
                //is leaf node
                if (listObj != null) {
                    //is ListBox
                    if (!isNotReturnMetaData && checkedNodesList[i].data.MetaData != "") {
                        //is return MetaData and MetaData is not empty
                        //add the node to ListBox
                        addItem(checkedNodesList[i].data.code, checkedNodesList[i].data.MetaData, listObj);
                    }
                    else if (isNotReturnMetaData) {
                        //is return label
                        //add the node to ListBox
                        addItem(checkedNodesList[i].data.code, checkedNodesList[i].data.label, listObj);
                    }
                } else {
                    //is not ListBox
                    codes = codes + checkedNodesList[i].data.code + splitChar;
                    
                    if (!isNotReturnMetaData && checkedNodesList[i].data.MetaData != "") {
                        //is return MetaData and MetaData is not empty
                        values = values + checkedNodesList[i].data.MetaData + splitChar;
                    }
                    else if (isNotReturnMetaData) {
                        //is return label
                        values = values + checkedNodesList[i].data.label + splitChar;
                    }
                }
            }
        }
        if (codes.length > 0 && values.length > 0 && returnCodeObj != null && returnNameObj != null) {
            //is not ListBox
            
            codes = codes.substring(0, codes.length - 1);
            
            values = values.substring(0, values.length - 1);
            
            
           
            returnCodeObj.value = codes;
            returnNameObj.value = values;
            
        }

        if (listObj != null) {
            //select an item in ListBox
            if (listObj.options.length > 0) {
                listObj.selectedIndex = listObj.options.length - 1;
            }
            listObj.focus();
        }
        
        //Hide dialog
        dialog.hide();
        setDisplay("none");
    };
    var handleCancel = function() {
        this.cancel();
    };
    //Handle for tree with checkbox end
    
    //Handle for tree without checkbox begin
    handleLabelClick = function(node) {
        if (node.isLeaf) {
            //is leaf node
            if (!isNotReturnMetaData && listObj != null) {
                //is ListBox and return MetaData
                addItem(node.data.code, node.data.MetaData, listObj, true)
            }
            else if (isNotReturnMetaData && listObj != null) {
                //is ListBox and return label
                addItem(node.data.code, node.data.label, listObj)
            }
            else if (listObj == null && returnCodeObj != null && returnNameObj != null) {
                //is TextBox
                returnCodeObj.value = node.data.code;
                if (!isNotReturnMetaData) {
                    //is return MetaData and MetaData is not empty
                    returnNameObj.value = node.data.MetaData;
                }
                else if (isNotReturnMetaData) {
                    //is return label
                    returnNameObj.value = node.data.label;
                }
            }

            //Hide dialog
            dialog.hide();
            setDisplay("none");
        } else if (!isExpandWhenClick) {
            //is not leaf node, and expand when click un-leaf node
            if (!isNotReturnMetaData && listObj != null) {
                //is ListBox and return MetaData
                addItem(node.data.code, node.data.MetaData, listObj)
            }
            else if (isNotReturnMetaData && listObj != null) {
                //is ListBox and return label
                addItem(node.data.code, node.data.label, listObj)
            }
            else {
                returnCodeObj.value = node.data.code;
                returnNameObj.value = node.data.label;
            }

            //Hide dialog
            dialog.hide();
            setDisplay("none");
        }
        if (listObj != null) {
            //select an item in ListBox
            if (listObj.options.length > 0) {
                listObj.selectedIndex = listObj.options.length - 1;
            }
            listObj.focus();
        }
        return isExpandWhenClick;
    }
    //Handle for tree without checkbox end
    function panelConfig(isDialog, isNotCheck) {
        if (isDialog && !isNotCheck)
        {
            //dialog checkbox tree
            dialog = new YAHOO.widget.Dialog(panelDivObj,
							        { width: width,
							            //context: [targetObj, "tl", "bl"],
							            fixedcenter: true,
							            visible: false,
							            constraintoviewport: true
							            , buttons: [{ text: confrimButtonText, handler: handleSubmit, isDefault: true },
							                  { text: cancelButtonText, handler: handleCancel}]
							        });
            dialog.render();
        } else if (isDialog && isNotCheck) {
            //dialog single tree
            dialog = new YAHOO.widget.Dialog(panelDivObj,
							        { width: width,
							            //context: [targetObj, "tl", "bl"],
							            fixedcenter: true,
							            visible: false,
							            constraintoviewport: true
							            //, buttons: [{ text: confrimButtonText, handler: handleSubmit, isDefault: true },
							            //      { text: cancelButtonText, handler: handleCancel}]
							        });
            dialog.render();
        } else if (!isDialog && !isNotCheck) {
            //panel checkbox tree
            if (targetObjId != null && !fixedcenter) {
                //fixed center
                dialog = new YAHOO.widget.Dialog(panelDivObj,
										{ width: width,
										    //context: [targetObj, "tl", "bl"],
										    fixedcenter: fixedcenter,
										    visible: false,
										    modal: false,
										    close: false,
										    draggable: false
										    , buttons: [{ text: confrimButtonText, handler: handleSubmit, isDefault: true },
							                  { text: cancelButtonText, handler: handleCancel}]
										});
            } else {
                //fixed targetObjId
                dialog = new YAHOO.widget.Dialog(panelDivObj,
										{ width: width,
										    context: [targetObj, "tl", "bl"],
										    fixedcenter: fixedcenter,
										    visible: false,
										    modal: false,
										    close: false,
										    draggable: false
										    , buttons: [{ text: confrimButtonText, handler: handleSubmit, isDefault: true },
							                  { text: cancelButtonText, handler: handleCancel}]
										});
            }
        } else if (!isDialog && isNotCheck) {
            //panel single tree
            if (targetObjId != null && !fixedcenter) {
                //fixed center
                dialog = new YAHOO.widget.Dialog(panelDivObj,
										{ width: width,
										    //context: [targetObj, "tl", "bl"],
										    fixedcenter: fixedcenter,
										    visible: false,
										    modal: false,
										    close: false,
										    draggable: false
										});
            } else {
                //fixed targetObjId
                dialog = new YAHOO.widget.Dialog(panelDivObj,
										{ width: width,
										    context: [targetObj, "tl", "bl"],
										    fixedcenter: fixedcenter,
										    visible: false,
										    modal: false,
										    close: false,
										    draggable: false
										});
            }
        } else {
            alert("Error paremeters.");
            return;
        }
        
    };
    
    
    try {
        treeDivObj.innerHTML = "<img src='../../_JS/ext_yui_tree/loading.gif' alt='' width='24' height='24' style='margin-right:8px;' align='absmiddle'/>";
        panelConfig(isDialog, isNotCheck);

        if (true == isNotCheck)
            loadTree(param);
        else
            loadTreeCheckBox(param);

        setDisplay("");
        dialog.show();
    }
    catch (e) {
        document.write("Exception Message:" + e.message)
    }

    //Auto hide when click out panel
    document.onmousedown = hanlderBlur;

    function hanlderBlur(e) {
        e = e ? e : window.event;
        var tag = e.srcElement ? e.srcElement : e.target;
        if (isBlur(tag, panelDivObj)) {
            if (typeof (dialog) != "undefined" || dialog != null) {
                dialog.hide();
            }
        }
    };

    isBlur = function(tag, id) {
        var b = true;
        var pNode = tag;
        while (true) {
            if (typeof (pNode) == "undefined" || pNode == null) {
                break;
            }
            if (pNode.id == id.id) {
                b = false;
                break;
            }
            pNode = pNode.parentNode;
        }
        return b;
    };

    function setDisplay(display) {
        var panel = document.getElementById(panelDivObj);
        if (panel != null) panel.style.display = display;
    };

    function getCheckedNodes(nodes) {
        var checkedNodes = [];
        for (var i = 0, l = nodes.length; i < l; i = i + 1) {
            var n = nodes[i];
            //if (n.checkState > 0) { // if we were interested in the nodes that have some but not all children checked
            if (n.checkState === 2) {
                checkedNodes.push(n); // just using label for simplicity
            }
            if (n.hasChildren()) {
                checkedNodes = checkedNodes.concat(getCheckedNodes(n.children));
            }
        }
        return checkedNodes;
    };

    function loadTreeCheckBox(param) {
        tree = new YAHOO.widget.TreeView(treeDivObj);
        var root = tree.getRoot();
        var callback = function(o) {
            if (o.error != null) {
                return;
            }
            if (o.value != null) {
                success(o);
            }
        };

        success = function(oResponse) {
            if (oResponse.value != "") {
                //alert(oResponse.value);
                var oResults = YAHOO.lang.JSON.parse(oResponse.value);
                //alert(oResults.Results.length);
                for (var i = 0; i < oResults.Results.length; i++) {
                    var tempNode = new YAHOO.widget.TaskNode(oResults.Results[i], root, false);
                    //only return leaf and no metadata
                    if (!isNotOnlyLeafCheck && tempNode.data.MetaData == "") {
                        tree.removeNode(tempNode, true);
                        tempNode = null;
                        if (oResults.Results[i].Children.length > 0)
                            tempNode = new YAHOO.widget.TextNode(oResults.Results[i], root, false);
                    }
                    if (tempNode != null) {
                        tempNode.expand();
                        if (oResults.Results[i].Children.length > 0) {
                            buildBranchCheckBox(oResults.Results[i].Children, tempNode);
                        }
                        if (tempNode.children.length == 0 && !isNotOnlyLeafCheck && tempNode.data.MetaData == "") {
                            tree.removeNode(tempNode, true);
                        }
                    }
                }
                //alert("");
                tree.draw();
            }

        };

        //Build branch for tree
        function buildBranchCheckBox(childrens, node) {
            for (var i = 0; i < childrens.length; i++) {
                var tempNode = new YAHOO.widget.TaskNode(childrens[i], node, false);
                if (!isNotOnlyLeafCheck && tempNode.data.MetaData == "") {
                    tree.removeNode(tempNode, true);
                    tempNode = null;
                    if (childrens[i].Children.length > 0)
                        tempNode = new YAHOO.widget.TextNode(childrens[i], node, false);

                }
                if (tempNode != null) {
                    if (childrens[i].Children.length > 0) {
                        buildBranchCheckBox(childrens[i].Children, tempNode);
                    }

                    if (tempNode.children.length == 0 && !isNotOnlyLeafCheck && tempNode.data.MetaData == "") {
                        tree.removeNode(tempNode, true);
                    }
                }
            }
        };
        className.LoadDatas(param, callback); //callback function
    };
    
    function loadTree(param) {
        try {
            tree = new YAHOO.widget.TreeView(treeDivObj);
            var root = tree.getRoot();
            var callback = function(root) {
                if (root.error != null) {
                    return;
                }
                if (root.value != null && root.value != '' && root.value != '') {
                    success(root);
                }
            };

            success = function(oResponse) {
                //alert(oResponse.value);
                var oResults = YAHOO.lang.JSON.parse(oResponse.value);
                for (var i = 0; i < oResults.Results.length; i++) {
                    var tempNode = new YAHOO.widget.TextNode(oResults.Results[i], root, false);
                    tempNode.expand();

                    if (oResults.Results[i].Children.length > 0) {
                        buildBranch(oResults.Results[i].Children, tempNode);
                    }
                    else {
                        tempNode.isLeaf = true;
                    }
                }
                tree.subscribe("labelClick", handleLabelClick);
                tree.draw();
            };
            className.LoadDatas(param, callback); 
        } catch (e) {
            document.write("Exception Message:" + e.message)
        }
    };

    //Build sub tree 
    function buildBranch(childrens, node) {
        try {
            for (var i = 0; i < childrens.length; i++) {
                var tempNode = new YAHOO.widget.TextNode(childrens[i], node, false);
                if (childrens[i].Children.length > 0) {
                    buildBranch(childrens[i].Children, tempNode);
                }
                else {
                    tempNode.isLeaf = true;
                }
            }
        }
        catch (e) {
            document.write("Exception Message:" + e.message)
        }
    };

    //Add item to ListBox
    function addItem(itemValue, itemText, list, isReplace) {
        if (true == isReplace) {
            //-> is for metadata flag
            var preFix;
            if (itemText.indexOf("->") != -1) {

                preFix = itemText.substr(0, itemText.indexOf("->"));
            }
            else {

                preFix = itemText;
            }
            if (false == chkDup(itemValue, list, preFix, isReplace)) {
                list.options.length++;
                list.options[list.options.length - 1].value = itemValue;
                list.options[list.options.length - 1].text = itemText;
            }
        }
        else {
            if (false == chkDup(itemValue, list)) {
                list.options.length++;
                list.options[list.options.length - 1].value = itemValue;
                list.options[list.options.length - 1].text = itemText;
            }
        }
    };

    //Check duplicate item
    function chkDup(itemValue, list, preFix, isReplace) {
        if (true == isReplace) {
            for (i = 0; i < list.options.length; i++) {
                if (itemValue == list.options[i].value) {
                    return true;
                }
                else {
                    var tmpPreFix = list.options[i].text;
                    if (tmpPreFix.indexOf("->") != -1) {
                        tmpPreFix = tmpPreFix.substr(0, tmpPreFix.indexOf("->"));
                    }
                    if (preFix == tmpPreFix) {
                        list.options.remove(i);
                        return false;
                    }
                }
            }
            return false;
        } else {
            for (i = 0; i < list.options.length; i++) {
                if (itemValue == list.options[i].value) {
                    return true;
                }
            }
            return false;
        }
    };
}